Bruno Rodrigues, head of the statistics and data strategy departments at the Ministry of Research and Higher education in Luxembourg
Using R since 2009
Slides available online at https://is.gd/nix_dipf
Code available at: https://github.com/b-rodrigues/dipf_workshop
Our focus today: the package manager
A word of warning: Nix is quite complex
It does require some time to learn on the user’s part
But {rix} will help
Package manager: tool to install and manage packages
Package: any piece of software (not just R packages)
A popular package manager:
Google Play Store
Make sure that the required/correct version of R (or any other language) is installed;
Make sure that the required versions of packages are installed;
Make sure that system dependencies are installed (for example, Java installation for rJava);
Make sure that you can install all of this for the hardware you have on hand.
{renv}, but deals with R packages onlyA popular approach: Docker + {renv} (see Rocker project)
Nix deals with everything, with one single text file (called a Nix expression)!
Nix: a functional package manager
Functional, as in, inspired by mathematical functions
Why math functions?
-> f(x)=y
Building a Nix expression always results in the same output
Output doesn’t depend on state of current system:
The idea is to always deploy component closures: if we deploy a component, then we must also deploy its dependencies, their dependencies, and so on. That is, we must always deploy a set of components that is closed under the ‘’depends on’’ relation. Since closures are selfcontained, they are the units of complete software deployment. After all, if a set of components is not closed, it is not safe to deploy, since using them might cause other components to be referenced that are missing on the target system.
Eelco Dolstra, Nix: A Safe and Policy-Free System for Software Deployment
let
pkgs = import (fetchTarball "https://github.com/NixOS/nixpkgs/archive/976fa3369d722e76f37c77493d99829540d43845.tar.gz") {};
system_packages = builtins.attrValues {
inherit (pkgs) R ;
};
in
pkgs.mkShell {
buildInputs = [ system_packages ];
shellHook = "R --vanilla";
}
There’s a lot to discuss here!
pkgs = import (fetchTarball "https://github.com/NixOS/nixpkgs/archive/976fa3369d722e76f37c77493d99829540d43845.tar.gz") {};
system_packages: a variable that lists software to installsystem_packages = builtins.attrValues {
inherit (pkgs) R ;
};
pkgs.mkShell {
buildInputs = [ system_packages ];
shellHook = "R --vanilla";
}
system_packages (buildInputs)R --vanilla when started (shellHook){rix} will help!nixpkgs in the rPackages set!{rix} (website) makes writing Nix expression easy!rix() function:rix::rix() generates a default.nix filenix-build (in terminal) or rix::nix_build() from Rnix-shell"dplyr@1.0.0")Let’s check out expressions/rix_intro/
{rix} makes it easy to run pipelines in the right environment{targets})expressions/nix_targets_pipelinecd /absolute/path/to/pipeline/ && nix-shell default.nix --run "Rscript -e 'targets::tar_make()'"
{targets} pipeline on Github actionsrix::tar_nix_ga() to generate the required filesexpressions/subshellrPackages set gets updated around new R releases (every 3 months or so)nixpkgs fork from our rstats-on-nix organisation!pkgs variable:pkgs = import (fetchTarball "https://github.com/rstats-on-nix/nixpkgs/archive/refs/heads/r-daily.tar.gz") {};
pkgs = import (fetchTarball "https://github.com/rstats-on-nix/nixpkgs/archive/78f705bd8689ad7d215f4b3aea9d9c1302a31b99.tar.gz") {};
{rix}Official Nix documentation: https://nix.dev/
Nix tutorial by INRIA: https://nix-tutorial.gitlabpages.inria.fr/nix-tutorial/
My blog: https://b-rodrigues.github.io/rix/
My book (doesn’t cover Nix, but Docker, {renv} and functional programming): https://raps-with-r.dev/